#ifndef BUCKETCHECK_H_
#define BUCKETCHECK_H_
#include <iostream>
#include <ros/ros.h>
#include <pcl/console/parse.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/io/pcd_io.h>
#include <pcl/pcl_base.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_line.h>
#include <pcl/sample_consensus/sac_model_circle.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <fstream>

#include <pcl/ModelCoefficients.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <sensor_msgs/LaserScan.h>

using namespace cv;
using namespace std;
using namespace sensor_msgs;

class BucketCheck
{
  public:
	BucketCheck();
  void laser_callback(const LaserScanConstPtr& laser);
  void bucketcheck(vector<long> data,vector<Eigen::VectorXf>& select_model_circles,vector<Eigen::VectorXf>& model_circles);
  /******************零像素筛选******************/
  void zero_select(vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud_clusters,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& final_lines,vector<float>& cluster_num);
  /******************点数筛选******************/
  void point_num_select(vector<long> data,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud_clusters,vector<float>& sum_average,vector<float>& cluster_num);
  /******************点数筛选重载******************/
  void point_num_select(vector<long> data,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud_clusters,vector<float>& sum_average,vector<float>& cluster_num,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& final_circles,vector<Eigen::VectorXf> &model_circles);
  /******************点云聚类******************/
  void cluster_select(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud_clusters);
  /******************直线拟合******************/
  void line_select(vector<float>& sum_average,vector<float>& cluster_num,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud_clusters,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& final_lines);
  /******************圆弧拟合******************/
  void circle_select(vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud_clusters,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& final_circles,vector<Eigen::VectorXf> &model_circles);
  /******************裁剪圆拟合******************/
  void cut_select(vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud_clusters,vector<float>& cluster_num,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& final_circles,vector<Eigen::VectorXf> &model_circles);
  /******************端点判别法******************/
  void teminal_select(vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud_clusters,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& final_circles,vector<Eigen::VectorXf> &model_circles);
  /******************斜率判别法******************/
  void slop_select(vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& cloud_clusters,vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>& final_circles,vector<Eigen::VectorXf> &model_circles);

  int select_bucket_radius_;
  vector<long> data_;
  std::basic_string<char> frame_id_;
  private:
  ros::NodeHandle nh_private_;
  int laser_type_;
  int target_bucket_radius_;             //条桶半径(cm)
  float target_circle_max_radius_;       //圆拟合最大半径(cm)
  float target_circle_min_radius_;       //圆拟合最小半径(cm)
  float rate_cluster_;            //每类应包含的点数量的比例

  bool if_bigBucket_select_;
  float select_circle_max_radius_;
  float select_circle_min_radius_;

  int bucket_radius_;
  float circle_max_radius_;
  float circle_min_radius_;

  ros::Subscriber sub_;
  ros::NodeHandle nh_;  ///< 全局句柄


  ros::Time stamp_;

};

#endif /* BUCKETCHECK_H_*/
